﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using Gendarme.Framework;
using System.Windows.Controls.Primitives;
using Microsoft.Win32;
using Commander.Core.Refactorings.Modifiers;
using System.IO;
using ICSharpCode.NRefactory;

namespace Commander.Prototype {
	/// <summary>
	/// Interaction logic for DefectLister.xaml
	/// </summary>
	public partial class DefectLister : UserControl {

		public ObservableCollection<Defect> Defects { get; private set; }
		const string PATH_REQUEST = "Please enter file path to class {0}:";

		public DefectLister() {
			InitializeComponent();
			NetWalkerCodeModifier.OnSpeculativeGenExtraInforRequired += new NetWalkerCodeModifier.SpeculativeGeneralityExtraInfoRequired(OnSpeculativeGenExtraInforRequired);
		}

		string OnSpeculativeGenExtraInforRequired(string variantClass) {
			MessageBox.Show(String.Format("Need class {0} to complete operation", variantClass));
			OpenFileDialog diag = new OpenFileDialog();
			diag.Multiselect = false;
			//diag.Filter = variantClass + ".cs";
			diag.ShowDialog();

			return File.ReadAllText(diag.FileName);
		}

		public void ProcessDefects(Collection<Defect> collection) {
			Defects = new ObservableCollection<Defect>(collection);
			this.defectList.ItemsSource = Defects;//collection[0].
		}

		private void refactorSmell_Click(object sender, RoutedEventArgs e) {
			if (defectList.SelectedIndex > -1) {
				var def = defectList.SelectedItem as Defect;
				if (def.CommanderExtra == null) {
					MessageBox.Show("Commander does not yet refactor smells of type: " + def.Rule.Name);
				}
				else {
					this.IsHitTestVisible = false;
					pathLabel.Content = String.Format(PATH_REQUEST, def.CommanderExtra.Attribute(Gendarme.Rules.Smells.CommanderSerializer.NAME).Value);
					extraFilePopup.IsOpen = true;
				}
			}
		}

		private void sourceFileSelect_Click(object sender, System.Windows.RoutedEventArgs e) {
			OpenFileDialog diag = new OpenFileDialog();
			diag.Multiselect = false;
			diag.ShowDialog();

			extraFilePopup.IsOpen = false;
			this.IsHitTestVisible = true;

			if (string.IsNullOrEmpty(diag.FileName)) {
				MessageBox.Show("Cannot proceed with the refactoring");
			}
			else {
				var def = defectList.SelectedItem as Defect;

				var origiContent = File.ReadAllText(diag.FileName);

				//Extra should be added inside Gendarme
				if (def.Rule.ToString().Equals("Gendarme.Rules.Smells.AvoidMessageChainsRule")) {
					def.CommanderExtra = new System.Xml.Linq.XElement("messageChain", 
						new System.Xml.Linq.XAttribute("src", def.Source),
						new System.Xml.Linq.XAttribute("path", diag.FileName));
				}

				var parser = ParserFactory.CreateParser(SupportedLanguage.CSharp, new StringReader(origiContent));
				parser.Parse();
				var refactContent = NetWalkerCodeModifier.CreateModifier(def.CommanderExtra, parser, def.Rule).ApplyModification();

				var view = new RefactoringView(origiContent, refactContent);
				view.Closed += new EventHandler(viewClosed);
				this.IsHitTestVisible = false;
				view.Show();

			}
		}

		private void explainSmell_Click(object sender, RoutedEventArgs e) {
			if (defectList.SelectedItem != null) {
				var view = new ExplanationView(defectList.SelectedItem as Defect);
				view.Closed += new EventHandler(viewClosed);
				this.IsHitTestVisible = false;
				view.Show();
			}
		}

		void viewClosed(object sender, EventArgs e) {
			this.IsHitTestVisible = true;
		}

		private void cancel_Click(object sender, System.Windows.RoutedEventArgs e) {
			extraFilePopup.IsOpen = false;
			this.IsHitTestVisible = true;
		}

		
	}
}
